package org.xielei.biztest.service;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.xielei.biztest.model.BizData;
import org.xielei.biztest.model.WxMsgTemplate;

import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;

/**
 * WxMsgTemplateService
 *
 * @author xielei
 * @date 2021/1/12
 */
public class WxMsgTemplateServiceTest {

    private WxMsgTemplate getWxMsgTemplate() {
        return WxMsgTemplate.builder()
                .templateId("templateId")
                .bizCode("testCode")
                .bizName("testName")
                .first("titleContent")
                .keyword1("hello, please check the orderCode ${0} of doctor ${1} for u")
                .keyword2("test ${0} and ${1} replace")
                .keyword3("请查看${0}医师为您开的推荐单${1}")
                .remark("thanks for ${0} watching")
                .build();
    }

    private BizData getBizData() {
        return BizData.builder()
                .keyword1List(new LinkedList<String>() {{
                    add("outTradeNo");
                    add("hou");
                }})
                .keyword2List(new LinkedList<String>() {{
                    add("\\$");
                    add("content");
                }})
                .keyword3List(new LinkedList<String>() {{
                    add("侯");
                    add("recommendId");
                }})
                .remarkList(new LinkedList<String>() {{
                    add("u");
                }})
                .build();
    }

    @Test
    public void replace() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        WxMsgTemplate wxMsgTemplate = getWxMsgTemplate();
        BizData bizData = getBizData();

        System.out.println(wxMsgTemplate.getKeyword1());
        Class<WxMsgTemplate> wxMsgTemplateClass = WxMsgTemplate.class;

        System.out.println(wxMsgTemplateClass.getName());

        System.out.println("------------------------------");

        for (Field field : wxMsgTemplateClass.getDeclaredFields()) {
            System.out.println("propertyName:" + field.getName());

            // get方法
            String methodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
            Method method = wxMsgTemplateClass.getMethod(methodName);
            String getValue = (String) method.invoke(wxMsgTemplate);
            System.out.println("getMethod value >>>>>>> " + getValue);

            // 替换 keyword i
            if (StringUtils.isNotBlank(getValue) && getValue.contains("${")) {
                int i = 0;
                String replacedContent = replaceContent(i, field.getName(), getValue, bizData);
                // set
                System.out.println("replaced content -----------> " + replacedContent);
                BeanUtils.setProperty(wxMsgTemplate, field.getName(), replacedContent);
            }
        }

        System.out.println("final result:" + wxMsgTemplate.toString());
    }

    private String replaceContent(int i, String fieldName, String getValue, BizData bizData) throws InvocationTargetException, IllegalAccessException {
        if (!getValue.contains("${")) {
            i = 0;
            return getValue;
        }

        Class<BizData> bizDataClass = BizData.class;
        for (Method method : bizDataClass.getMethods()) {
            if (!method.getName().toLowerCase().contains("get")) {
                continue;
            }
            if (!method.getName().toLowerCase().contains(fieldName.toLowerCase())) {
                continue;
            }

            System.out.println("bizData method name:" + method.getName());
            LinkedList<String> getValueList = (LinkedList<String>) method.invoke(bizData);
            System.out.println("replace value:" + getValueList.toString());
            getValue = getValue.replaceAll("\\$\\{" + i + "}", getValueList.get(i));
            System.out.println("getValue replace:" + getValue);
            break;
        }
        i += 1;
        return replaceContent(i, fieldName, getValue, bizData);
    }
}
